/**
 * @class L.EditToolbar.Delete
 * @aka EditToolbar.Delete
 */
L.EditToolbar.Delete = L.Handler.extend({
    statics: {
        TYPE: 'remove' // not delete as delete is reserved in js
    },

    // @method intialize(): void
    initialize: function (map, options) {
        L.Handler.prototype.initialize.call(this, map);

        L.Util.setOptions(this, options);

        // Store the selectable layer group for ease of access
        this._deletableLayers = this.options.featureGroup;

        if (!(this._deletableLayers instanceof L.FeatureGroup)) {
            throw new Error('options.featureGroup must be a L.FeatureGroup');
        }

        // Save the type so super can fire, need to do this as cannot do this.TYPE :(
        this.type = L.EditToolbar.Delete.TYPE;

        var version = L.version.split('.');
        //If Version is >= 1.2.0
        if (parseInt(version[0], 10) === 1 && parseInt(version[1], 10) >= 2) {
            L.EditToolbar.Delete.include(L.Evented.prototype);
        } else {
            L.EditToolbar.Delete.include(L.Mixin.Events);
        }

    },

    // @method enable(): void
    // Enable the delete toolbar
    enable: function () {
        if (this._enabled || !this._hasAvailableLayers()) {
            return;
        }
        this.fire('enabled', {handler: this.type});

        this._map.fire(L.Draw.Event.DELETESTART, {handler: this.type});

        L.Handler.prototype.enable.call(this);

        this._deletableLayers
            .on('layeradd', this._enableLayerDelete, this)
            .on('layerremove', this._disableLayerDelete, this);
    },

    // @method disable(): void
    // Disable the delete toolbar
    disable: function () {
        if (!this._enabled) {
            return;
        }

        this._deletableLayers
            .off('layeradd', this._enableLayerDelete, this)
            .off('layerremove', this._disableLayerDelete, this);

        L.Handler.prototype.disable.call(this);

        this._map.fire(L.Draw.Event.DELETESTOP, {handler: this.type});

        this.fire('disabled', {handler: this.type});
    },

    // @method addHooks(): void
    // Add listener hooks to this handler
    addHooks: function () {
        var map = this._map;

        if (map) {
            map.getContainer().focus();

            this._deletableLayers.eachLayer(this._enableLayerDelete, this);
            this._deletedLayers = new L.LayerGroup();

            this._tooltip = new L.Draw.Tooltip(this._map);
            this._tooltip.updateContent({text: L.drawLocal.edit.handlers.remove.tooltip.text});

            this._map.on('mousemove', this._onMouseMove, this);
        }
    },

    // @method removeHooks(): void
    // Remove listener hooks from this handler
    removeHooks: function () {
        if (this._map) {
            this._deletableLayers.eachLayer(this._disableLayerDelete, this);
            this._deletedLayers = null;

            this._tooltip.dispose();
            this._tooltip = null;

            this._map.off('mousemove', this._onMouseMove, this);
        }
    },

    // @method revertLayers(): void
    // Revert the deleted layers back to their prior state.
    revertLayers: function () {
        // Iterate of the deleted layers and add them back into the featureGroup
        this._deletedLayers.eachLayer(function (layer) {
            this._deletableLayers.addLayer(layer);
            layer.fire('revert-deleted', {layer: layer});
        }, this);
    },

    // @method save(): void
    // Save deleted layers
    save: function () {
        this._map.fire(L.Draw.Event.DELETED, {layers: this._deletedLayers});
    },

    // @method removeAllLayers(): void
    // Remove all delateable layers
    removeAllLayers: function () {
        // Iterate of the delateable layers and add remove them
        this._deletableLayers.eachLayer(function (layer) {
            this._removeLayer({layer: layer});
        }, this);
        this.save();
    },

    _enableLayerDelete: function (e) {
        var layer = e.layer || e.target || e;

        layer.on('click', this._removeLayer, this);
    },

    _disableLayerDelete: function (e) {
        var layer = e.layer || e.target || e;

        layer.off('click', this._removeLayer, this);

        // Remove from the deleted layers so we can't accidentally revert if the user presses cancel
        this._deletedLayers.removeLayer(layer);
    },

    _removeLayer: function (e) {
        var layer = e.layer || e.target || e;

        this._deletableLayers.removeLayer(layer);

        this._deletedLayers.addLayer(layer);

        layer.fire('deleted');
    },

    _onMouseMove: function (e) {
        this._tooltip.updatePosition(e.latlng);
    },

    _hasAvailableLayers: function () {
        return this._deletableLayers.getLayers().length !== 0;
    }
});